package main

import (
	"fmt"
	"github.com/go-gl/gl/v4.5-core/gl"
	"github.com/go-gl/glfw/v3.2/glfw"
	"io/ioutil"
	"runtime"
)

func init() {
	// This is needed to arrange that main() runs on main thread.
	// See documentation for functions that are only allowed to be called from the main thread.
	runtime.LockOSThread()
}

func main() {
	if err := glfw.Init(); err != nil {
		panic(err)
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.ContextVersionMajor, 4)
	glfw.WindowHint(glfw.ContextVersionMinor, 5)
	glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
	glfw.WindowHint(glfw.Resizable, glfw.False)

	window, err := glfw.CreateWindow(1280, 720, "测试glfw", nil, nil)
	if err != nil {
		panic(err)
	}

	window.MakeContextCurrent()
	var width, height = window.GetFramebufferSize()
	fmt.Println(width, ` * `, height)

	//###这个很重要，初始化OpenGL，不初始化就调用函数的话程序直接崩溃
	if err := gl.Init(); err != nil {
		panic(err)
	}
	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("OpenGL version", version)
	glVersion := gl.GoStr(gl.GetString(gl.SHADING_LANGUAGE_VERSION))
	fmt.Println("GLSL version", glVersion)
	var maxV int64
	gl.GetInteger64v(gl.MAX_VERTEX_ATTRIBS, &maxV)
	fmt.Println("MAX_VERTEX_ATTRIBS：", maxV)

	gl.Viewport(0, 0, int32(width), int32(height))

	vertexShader, err := ioutil.ReadFile(`./vertexShader.vs`)
	if err != nil {
		panic(err)
	} else {
		fmt.Println("读取顶点着色器成功")
	}
	fragmentShader, err := ioutil.ReadFile(`./fragmentShader.fs`)
	if err != nil {
		panic(err)
	} else {
		fmt.Println("读取像素着色器成功")
	}
	fragmentShader2, err := ioutil.ReadFile(`./fragmentShader2.fs`)
	if err != nil {
		panic(err)
	} else {
		fmt.Println("读取像素着色器2成功")
	}
	//fmt.Println(string(vertexShader))
	//fmt.Println(string(fragmentShader))

	// 配置顶点着色器和像素着色器
	program, err := newProgram(string(vertexShader)+"\x00", string(fragmentShader)+"\x00")
	if err != nil {
		panic(err)
	}

	program2, err := newProgram(string(vertexShader)+"\x00", string(fragmentShader2)+"\x00")
	if err != nil {
		panic(err)
	}

	//三角形的设备坐标
	const (
		STRIDE = 3 * 4 //步长，即每个顶点的byte数量
	)
	var vertices = []float32{
		0.0, 0.5, 0.0, // 左上角
		0.5, 0.5, 0.0, // 右上角
		0.0, 0.0, 0.0, // 左下角
		0.5, 0.0, 0.0, // 右下角
		-0.5, -0.5, 0.0,
	}
	var indices = []uint32{
		0, 1, 2,
		1, 2, 3,
		2, 3, 4,
		0, 2, 4,
	}
	var VBO, VAO, EBO uint32
	gl.GenVertexArrays(1, &VAO)
	gl.GenBuffers(1, &VBO)
	gl.GenBuffers(1, &EBO)

	gl.BindVertexArray(VAO)

	gl.BindBuffer(gl.ARRAY_BUFFER, VBO)
	gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW)

	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, EBO)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*4, gl.Ptr(indices), gl.STATIC_DRAW)

	gl.EnableVertexAttribArray(0)
	gl.VertexAttribPointer(0, 3, gl.FLOAT, false, STRIDE, gl.PtrOffset(0))

	//gl.BindVertexArray(0)
	fmt.Print(VBO, EBO)

	for !window.ShouldClose() {
		///*// Do OpenGL stuff.
		gl.ClearColor(0.0, 0.0, 0.0, 1.0)
		gl.Clear(gl.COLOR_BUFFER_BIT)

		//gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE)

		gl.UseProgram(program)
		gl.BindVertexArray(VAO)
		gl.DrawElements(gl.TRIANGLES, 2*3, gl.UNSIGNED_INT, gl.PtrOffset(0))

		gl.UseProgram(program2)
		//gl.BindVertexArray(VAO)
		gl.DrawElements(gl.TRIANGLES, 2*3, gl.UNSIGNED_INT, gl.PtrOffset(2*3*4))

		//Do OpenGL stuff.*/
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
